home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
xlib06p1.zip
/
XSCALEBM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-15
|
9KB
|
277 lines
#include "xinternl.h"
#include <conio.h>
/*==================================================================
XSCALEBM.CPP contains the basic functions for bitmap scaling in
mode X.
These routines were written initially by John P. Slagel and
company and modified March 1995 by Victor B. Putz.
===================================================================*/
extern xScreenCoord_t LeftClip;
extern xScreenCoord_t RightClip;
extern xScreenCoord_t TopClip;
extern xScreenCoord_t BottomClip;
extern int ScrnLogicalByteWidth;
extern BYTE * pbVGABuffer;
void x_scale_bm(
xScreenCoord_t iDestX,
xScreenCoord_t iDestY,
int iDestWidth,
int iDestHeight,
xPageHandle_t ScrnOffs,
BYTE * pbData
)
{
//get width and height;
int iSourceWidth = *pbData++;
int iSourceHeight = *pbData++;
//now check for "too small" puts ( width or height < 2 )
if ( ( iDestWidth < 2 ) ||
( iDestHeight < 2 ) ) {
return;
}
//now check for out-of-bounds puts, basing of pixel-sized clipping
//boundaries ( rather than nibble-sized clipping boundaries )
int iLeftPixelClip = LeftClip << 2;
int iRightPixelClip = RightClip << 2;
if ( ( iDestY > BottomClip ) ||
( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
( iDestX > iRightPixelClip ) ||
( ( iDestY + iDestWidth - 1 ) < iLeftPixelClip ) ) {
return;
}
//for now, clipped width = destination width, set up decision X variable
int iClippedWidth = iDestWidth;
int iDecisionX = -iDestWidth;
//clipped height and decision Y variable
int iClippedHeight = iDestHeight;
int iDecisionY = -iDestHeight;
//...and offset into source map
int iSourceOffset = 0;
//check for clipping in the Y axis, first checking top
if ( iDestY < TopClip ) {
int iClippedRows = TopClip - iDestY;
iClippedHeight -= iClippedRows;
iDestY = TopClip;
for ( int i = iClippedRows; i > 0; --i ) {
iDecisionY += iSourceHeight;
if ( iDecisionY >= 0 ) {
while ( iDecisionY >= 0 ) {
iDecisionY -= iDestHeight;
iSourceOffset += iSourceWidth;
}
}
}
}
//then checking bottom...
int iBottomRow = iDestY + iClippedHeight - 1;
if ( iBottomRow > BottomClip ) {
iClippedHeight -= ( iBottomRow - BottomClip );
}
//then check for left clipping...
if ( iDestX < iLeftPixelClip ) {
int iClippedColumns = iLeftPixelClip - iDestX;
iClippedWidth -= iClippedColumns;
iDestX = iLeftPixelClip;
for ( int i = iClippedColumns; i > 0; --i ) {
iDecisionX += iSourceWidth;
if ( iDecisionX >= 0 ) {
while ( iDecisionX >= 0 ) {
iDecisionX -= iDestWidth;
iSourceOffset++;
}
}
}
}
int iRightRow = iDestX + iClippedWidth - 1;
if ( iRightRow > iRightPixelClip ) {
iClippedWidth -= ( iRightRow - iRightPixelClip );
}
//Okay! The clipping is done, so let's find our source and
//destination pointers.
BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
BYTE * pbSource = pbData + iSourceOffset;
int iWidthCounter = iClippedWidth;
//set up the controller to switch planes
outp( SC_INDEX, MAP_MASK );
int iPlane = iDestX & 0x03;
outp( SC_INDEX + 1, 1 << iPlane );
//now set up some "old position" pointers so we can rewind reliably
BYTE * pbDestStart = pbDest;
BYTE * pbSourceStart = pbSource;
while ( iWidthCounter-- ) {
int iHeightCounter = iClippedHeight;
int iDecisionYCount = iDecisionY;
BYTE b = *pbSource;
while ( iHeightCounter-- ) {
//plot the pixel and go to the next pixel down.
*pbDest = b;
pbDest += ScrnLogicalByteWidth;
//now increment our decision Y variable and get the next source
//pixel if need be
iDecisionYCount += iSourceHeight;
if ( iDecisionYCount >= 0 ) {
while ( iDecisionYCount >= 0 ) {
iDecisionYCount -= iDestHeight;
pbSource += iSourceWidth;
}
b = *pbSource;
}
}
//now go to the next screen column
++iPlane;
//if we've wrapped over our 4-plane boundary, increase the VGA start
//by one pixel.
if ( iPlane & 0x04 ) {
pbDestStart++;
iPlane &= 0x03;
}
outp( SC_INDEX + 1, 1 << iPlane );
pbDest = pbDestStart;
//now increment our decision X variable and go to the next source column
//if need be;
iDecisionX += iSourceWidth;
if ( iDecisionX >= 0 ) {
while ( iDecisionX >= 0 ) {
iDecisionX -= iDestWidth;
pbSourceStart++;
}
}
pbSource = pbSourceStart;
}
}
/*
The scaling version of the routine is the exact same code, with the addition
of a check to make sure the color is not zero before blitting.
*/
void x_scale_masked_bm(
xScreenCoord_t iDestX,
xScreenCoord_t iDestY,
int iDestWidth,
int iDestHeight,
xPageHandle_t ScrnOffs,
BYTE * pbData
)
{
//get width and height;
int iSourceWidth = *pbData++;
int iSourceHeight = *pbData++;
//now check for "too small" puts ( width or height < 2 )
if ( ( iDestWidth < 2 ) ||
( iDestHeight < 2 ) ) {
return;
}
//now check for out-of-bounds puts, basing of pixel-sized clipping
//boundaries ( rather than nibble-sized clipping boundaries )
int iLeftPixelClip = LeftClip << 2;
int iRightPixelClip = RightClip << 2;
if ( ( iDestY > BottomClip ) ||
( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
( iDestX > iRightPixelClip ) ||
( ( iDestX + iDestWidth - 1 ) < iLeftPixelClip ) ) {
return;
}
//for now, clipped width = destination width, set up decision X variable
int iClippedWidth = iDestWidth;
int iDecisionX = -iDestWidth;
//clipped height and decision Y variable
int iClippedHeight = iDestHeight;
int iDecisionY = -iDestHeight;
//...and offset into source map
int iSourceOffset = 0;
//check for clipping in the Y axis, first checking top
if ( iDestY < TopClip ) {
int iClippedRows = TopClip - iDestY;
iClippedHeight -= iClippedRows;
iSourceOffset += iClippedRows * iSourceWidth;
iDestY = TopClip;
iDecisionY += iClippedRows * iSourceHeight;
while ( iDecisionY > 0 ) {
iDecisionY -= iDestHeight;
}
}
//then checking bottom...
int iBottomRow = iDestY + iClippedHeight - 1;
if ( iBottomRow > BottomClip ) {
iClippedHeight -= ( iBottomRow - BottomClip );
}
//then check for left clipping...
if ( iDestX < iLeftPixelClip ) {
int iClippedColumns = iLeftPixelClip - iDestX;
iClippedWidth -= iClippedColumns;
iSourceOffset += iClippedColumns;
iDestX = iLeftPixelClip;
iDecisionX += iClippedColumns * iSourceWidth;
while ( iDecisionX > 0 ) {
iDecisionX -= iDestWidth;
}
}
int iRightRow = iDestX + iClippedWidth - 1;
if ( iRightRow > iRightPixelClip ) {
iClippedWidth -= ( iRightRow - iRightPixelClip );
}
//Okay! The clipping is done, so let's find our source and
//destination pointers.
BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
BYTE * pbSource = pbData + iSourceOffset;
int iWidthCounter = iClippedWidth;
//set up the controller to switch planes
outp( SC_INDEX, MAP_MASK );
int iPlane = iDestX & 0x03;
outp( SC_INDEX + 1, 1 << iPlane );
//now set up some "old position" pointers so we can rewind reliably
BYTE * pbDestStart = pbDest;
BYTE * pbSourceStart = pbSource;
while ( iWidthCounter-- ) {
int iHeightCounter = iClippedHeight;
int iDecisionYCount = iDecisionY;
BYTE b = *pbSource;
while ( iHeightCounter-- ) {
//plot the pixel and go to the next pixel down.
if ( b != 0 ) {
*pbDest = b;
}
pbDest += ScrnLogicalByteWidth;
//now increment our decision Y variable and get the next source
//pixel if need be
iDecisionYCount += iSourceHeight;
if ( iDecisionYCount >= 0 ) {
while ( iDecisionYCount >= 0 ) {
iDecisionYCount -= iDestHeight;
pbSource += iSourceWidth;
}
b = *pbSource;
}
}
//now go to the next screen column
++iPlane;
//if we've wrapped over our 4-plane boundary, increase the VGA start
//by one pixel.
if ( iPlane & 0x04 ) {
pbDestStart++;
iPlane &= 0x03;
}
outp( SC_INDEX + 1, 1 << iPlane );
pbDest = pbDestStart;
//now increment our decision X variable and go to the next source column
//if need be;
iDecisionX += iSourceWidth;
if ( iDecisionX >= 0 ) {
while ( iDecisionX >= 0 ) {
iDecisionX -= iDestWidth;
pbSourceStart++;
}
}
pbSource = pbSourceStart;
}
}